
/*
 * sndpipe: A UNIX pipes-based audio stream processor toolkit.
 * Copyright (C) 2011  Bradley Worley
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to:
 *
 *   Free Software Foundation, Inc.
 *   51 Franklin Street, Fifth Floor
 *   Boston, MA  02110-1301, USA.
 */

/* include the sndpipe header. */
#include "sndpipe.h"

/* func_del: initiates the DEL functionality.
 *
 * this function opens up an input and output pipe (both are required)
 * and passes through all input channels to the output except for the
 * requested (deleted) channel.
 */
void func_del (void) {
  /* declare required variables. */
  unsigned long c, i, frames;
  struct pipes *pi, *po;
  double **buf;
  SF_INFO sfi;

  /* declare required deletion variables. */
  unsigned long cdel;

  /* read in the deleted channel number. */
  cdel = opts_get_int (OPTS_S_CHANNEL);

  /* ensure the deleted channel number was supplied. */
  if (!cdel) {
    /* print a failure message and exit the application. */
    failf ("unable to retrieve deleted channel number");
  }

  /* zero out the sndfile information structure. */
  memset (&sfi, 0, sizeof (sfi));

  /* attempt to open the input pipe. */
  pi = pipes_open_input ();

  /* ensure the input pipe was successfully opened. */
  if (!pi) {
    /* print a failure message and exit the application. */
    failf ("unable to open input pipe");
  }

  /* set the output pipe options directly from the input pipe. */
  sfi.samplerate = pi->sfi.samplerate;
  sfi.channels = pi->sfi.channels - 1;
  sfi.format = pi->sfi.format;

  /* ensure we have an output format. */
  if (!sfi.format) {
    /* print a failure message and exit the application. */
    failf ("unable to retrieve pipes output format");
  }

  /* open the output pipes structure and allocate the buffer memory. */
  frames = 0;
  po = pipes_open_output (sfi);
  buf = pipes_buf_alloc (pi, &frames);

  /* loop while we can write samples to the pipe. */
  do {
    /* attempt to read from the input pipe. */
    if (pipes_read (pi, &buf, frames) != SP_OK) {
      /* print a failure message and break the loop. */
      warnf ("unable to read from input audio pipe");
      break;
    }

    /* loop through the shifted channels. */
    for (c = cdel; c < pi->sfi.channels; c++) {
      /* loop through the number of data frames, performing the shift. */
      for (i = 0; i < frames; i++) buf[c - 1][i] = buf[c][i];
    }
  } while (pipes_write (po, buf, frames) == SP_OK);

  /* free the output pipes buffer memory. */
  pipes_buf_free (pi, frames, buf);

  /* attempt to close the input pipe. */
  if (pipes_close (pi) != SP_OK) {
    /* print a failure message and exit the application. */
    failf ("unable to close input pipe");
  }

  /* attempt to close the output pipe. */
  if (pipes_close (po) != SP_OK) {
    /* print a failure message and exit the application. */
    failf ("unable to close output pipe");
  }
}

